home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / origami / foldfiling.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  22.8 KB  |  883 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #ifdef CONFIG_H
  4. #   include "config.h"
  5. #endif
  6.  
  7. #include <sys/types.h>
  8. #include <ctype.h>
  9. #include <unistd.h>
  10. #include <limits.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <sys/stat.h>
  15.  
  16. #define FOLDFILING_C
  17. #define I_BUFFLOOP_C
  18. #define I_DISPLAY_C
  19. #define I_FINDS_C
  20. #define I_FOLDHELP_C
  21. #define I_FOLDING_C
  22. #define I_GETMSG_C
  23. #define I_GETTK_C
  24. #define I_KEYBOARD_C
  25. #define I_LOOP_C
  26. #define I_MESSAGES_C
  27. #define I_MISC_C
  28. #define I_ORIEDT_C
  29. #define I_PROMPT_C
  30. #define I_READFOLDS_C
  31. #define I_SCREEN_C
  32. #define I_SHELL_C
  33. #define I_SIGNALS_C
  34. #define I_VIRTUAL_C
  35. #define I_WRITEF_C
  36.  
  37. #include "origami.h"
  38. #include <lib/ori_add_lib.h>
  39. /*}}}  */
  40.  
  41. /*{{{  type edit_file_buffer*/
  42. typedef struct edit_file_buffer
  43.  { char const *filename;
  44.    int last_line;
  45.    struct edit_file_buffer *next;
  46.  } edit_file_buffer;
  47. /*}}}  */
  48. /*{{{  variable*/
  49. private edit_file_buffer *cmd_last=0;
  50. private edit_file_buffer *current_ring_file=0;
  51. private edit_file_buffer default_ring={ 0,0,&default_ring };
  52. private int ring_size=1;
  53. private edit_file_buffer *file_ring= &default_ring;
  54. /*}}}  */
  55.  
  56. /*{{{  cut_filename*/
  57. private void cut_filename(unsigned char *buff,unsigned char const *s)
  58. {
  59.   int i;
  60.   unsigned char c;
  61.  
  62.   for
  63.    ( i=0;
  64.      (c= *s) && c!=' ' && c!='\t' && i<_POSIX_PATH_MAX;
  65.      buff[i++]= c,s++
  66.    );
  67.   buff[i]='\0';
  68. }
  69. /*}}}  */
  70. /*{{{  save_lang*/
  71. public void save_lang(struct lg_dumb * const d)
  72. {
  73.   *d=bd.m.dialect;
  74.   d->lg=dialects[F_C_USER].lg;
  75. }
  76. /*}}}  */
  77. /*{{{  reset_lang*/
  78. public void reset_lang(struct lg_dumb * const d)
  79. {
  80.   bd.m.dialect= *d;
  81.   dialects[F_C_USER].lg=d->lg;
  82. }
  83. /*}}}  */
  84. /*{{{  proc_language*/
  85. public void proc_language(void)
  86. {
  87.   if (bd.m.dialect.typ!=F_C_TDS || yes(get_msg(M_LEAVE_INMOS)))
  88.    /*{{{  get and set new dialect*/
  89.    { struct lg_dumb d;
  90.      unsigned char m_buff[LINELEN+1];
  91.  
  92.      /*{{{  prepare menu string*/
  93.      { f_c_types i;
  94.  
  95.        for (i=F_C_NONE,m_buff[0]='\0';i<F_C_SIZE;i++)
  96.         { ustrcat(m_buff,((i>=F_C_USER)?two_space:one_space));
  97.           ustrcat(m_buff,dialects[i].name);
  98.         }
  99.      }
  100.      /*}}}  */
  101.      d.typ=menu_item(m_buff,bd.m.dialect.typ,False,True);
  102.      if (d.typ>=F_C_NONE && d.typ<=F_C_TDS)
  103.       /*{{{  set new dialect*/
  104.       { if (bd.m.dialect.typ!=d.typ || bd.m.dialect.typ==F_C_USER)
  105.          { switch (d.typ)
  106.             { case F_C_USER:
  107.                /*{{{  get user-comments*/
  108.                { s_readprompt(d.lg_u_s,get_msg(M_CO_START),FOLD_COMMENT_LENGTH,no_history);
  109.                  if (aborted)
  110.                     break;
  111.                  s_readprompt(d.lg_u_e,get_msg(M_CO_END),FOLD_COMMENT_LENGTH,no_history);
  112.                  if (aborted)
  113.                     break;
  114.                  d.lg.start=ustrlen(d.lg_u_s);
  115.                  d.lg.end=ustrlen(d.lg_u_e);
  116.                  reset_lang(&d);
  117.                }
  118.                /*}}}  */
  119.               default:
  120.                  title_op(CHGTITLE);
  121.                  bd.m.dialect.typ=d.typ;
  122.                  no_message();
  123.                  return;
  124.             }
  125.          }
  126.       }
  127.       /*}}}  */
  128.    }
  129.    /*}}}  */
  130.   try_unchange();
  131.   no_message();
  132. }
  133. /*}}}  */
  134. /*{{{  file_fold*/
  135. public void file_fold
  136.  ( unsigned char const * const save_name,
  137.    FILE * const read_pipe
  138.  )
  139. {
  140.   msgtyp ff_msg;
  141.   unsigned char newfilename[_POSIX_PATH_MAX+1];
  142.   unsigned char exfilename[_POSIX_PATH_MAX+1];
  143.  
  144.   ff_msg=M_NO_SIMPLE_FOLD;
  145.   ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
  146.   if (normal_att(&(bd.f.current->x.fold),True))
  147.    { switch((bd.f.cur_line_typ=get_linetyp(*bd.f.current)))
  148.       { default:
  149.            goto ff_error;
  150.         case START_FOLD:
  151.          /*{{{  file*/
  152.          { FILE *fp;
  153.            boolean can_open;
  154.  
  155.            check_fold(bd.f.current);
  156.            if (save_name)
  157.             /*{{{  use given name*/
  158.             { ustrcpy(newfilename,save_name);
  159.               ustrcpy(exfilename,save_name);
  160.             }
  161.             /*}}}  */
  162.            else
  163.             /*{{{  create new name from fold comment*/
  164.             { cut_filename(newfilename,get_data(bd.f.Start_of_fold));
  165.               ustrcpy(exfilename,newfilename);
  166.               home_expand((char*)exfilename);
  167.             }
  168.             /*}}}  */
  169.            if (access((char *)exfilename, F_OK|R_OK|W_OK)==0)
  170.               can_open=yes(get_msg(F_TCFF,newfilename));
  171.            else if ((fp=fopen((char *)exfilename,(char*)"w")))
  172.             { fclose(fp);
  173.               can_open=True;
  174.             }
  175.            else
  176.              can_open=False;
  177.            if (!can_open)
  178.             { ff_msg=F_NO_OPEN;
  179.               goto ff_error;
  180.             }
  181.            set_data(bd.f.End_of_fold,exfilename,False);
  182.            write_fold(exfilename,bd.f.Start_of_fold,(FILE*)0);
  183.            if (bd.f.Start_of_fold->x.fold.data != bd.f.End_of_fold)
  184.               delete_list(bd.f.Start_of_fold->x.fold.data, bd.f.End_of_fold->prec);
  185.            bd.f.Start_of_fold->x.fold.data = bd.f.End_of_fold;
  186.            bd.f.End_of_fold->prec = bd.f.Start_of_fold;
  187.            set_linetyp(*bd.f.Start_of_fold,START_FILED);
  188.            break;
  189.          }
  190.          /*}}}  */
  191.         case START_FILED:
  192.          /*{{{  unfile*/
  193.          { boolean oldview;
  194.            unsigned char f_buff[_POSIX_PATH_MAX+1];
  195.            struct lg_dumb lang_dump;
  196.            
  197.            save_lang(&lang_dump);
  198.            oldview=bd.m.read_only;
  199.            pre_open_fold(bd.f.current);
  200.            ustrcpy(f_buff,get_data(bd.f.End_of_fold));
  201.            home_expand((char*)f_buff);
  202.            set_data(bd.f.End_of_fold,f_buff,False);
  203.            if (bd.f.Start_of_fold->next == bd.f.End_of_fold)
  204.                insert_file(bd.f.End_of_fold,
  205.                            bd.f.Start_of_fold,
  206.                            bd.f.End_of_fold,
  207.                            False,
  208.                            bd.f.real_head,
  209.                            (boolean*)0,
  210.                            (boolean*)0,
  211.                            read_pipe);
  212.            close_fold_at(bd.f.current);
  213.            reset_lang(&lang_dump);
  214.            bd.m.read_only=oldview;
  215.            break;
  216.          }
  217.          /*}}}  */
  218.       }
  219.      bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  220.      write_dsp_line(bd.f.current, bd.scr.cursor.h);
  221.      return;
  222.    }
  223. ff_error:
  224.   message(get_msg(ff_msg,newfilename));
  225.   try_unchange();
  226.   return;
  227. }
  228. /*}}}  */
  229. /*{{{  attach_file*/
  230. public void attach_file(void)
  231. {
  232.   ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
  233.   switch (bd.f.cur_line_typ)
  234.    { case START_FOLD:
  235.       { if (normal_att(&(bd.f.current->x.fold),False))
  236.          { check_fold(bd.f.current);
  237.            if (bd.f.Start_of_fold->x.fold.data == bd.f.End_of_fold)
  238.             { unsigned char filename[_POSIX_PATH_MAX+1];
  239.  
  240.               cut_filename(filename,get_data(bd.f.Start_of_fold));
  241.               home_expand((char*)filename);
  242.               if (access((char *)filename,R_OK)==-1)
  243.                  if
  244.                   /*{{{  can get dirname(current-file)/name*/
  245.                   (    bd.f.real_tail!=bd.f.real_head
  246.                     && join_fd(filename,get_data(bd.f.real_tail))
  247.                   )
  248.                   /*}}}  */
  249.                   /*{{{  test if existing*/
  250.                     if (access((char *)filename,R_OK) == -1)
  251.                        goto attach_cant_open;
  252.                     else
  253.                      { warn_message(get_msg(F_ADD_PATH,filename));
  254.                        set_data(bd.f.Start_of_fold,filename,False);
  255.                      }
  256.                   /*}}}  */
  257.                  else
  258.                   /*{{{  cannot open file*/
  259.                   { attach_cant_open:
  260.  
  261.                     message
  262.                      ( get_msg
  263.                         ( F_F_FAILED,
  264.                           get_data(bd.f.Start_of_fold))
  265.                      );
  266.                     return;
  267.                   }
  268.                   /*}}}  */
  269.               set_data(bd.f.End_of_fold,get_data(bd.f.Start_of_fold),False);
  270.               set_linetyp(*bd.f.Start_of_fold,START_FILED);
  271.               write_dsp_line(bd.f.current, bd.scr.cursor.h);
  272.               return;
  273.             }
  274.          }
  275.         break;
  276.       }
  277.      case START_FILED:
  278.         set_data(bd.f.current->x.fold.other_end,empty_text,False);
  279.         ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
  280.         set_linetyp(*bd.f.current,bd.f.cur_line_typ=START_FOLD);
  281.         bd.f.current->x.fold.UU.U1.type = DEFAULT_TYPE;
  282.         bd.f.current->x.fold.UU.U1.contents = TEXT_CONTENTS;
  283.         write_dsp_line(bd.f.current, bd.scr.cursor.h);
  284.         return;
  285.      default:
  286.         break;
  287.    }
  288.   try_unchange();
  289. }
  290. /*}}}  */
  291. /*{{{  filter_op*/
  292. /*{{{  filter_line*/
  293. private void filter_line(boolean text,unsigned char *filter)
  294. { unsigned char tmp_file[_POSIX_PATH_MAX+1];
  295.   FILE *read_pipe;
  296.  
  297.   /*{{{  write line to file*/
  298.   tmpnam((char*)tmp_file);
  299.   if (text)
  300.    /*{{{  fold the textline*/
  301.    { bd.scr.cursor.w=bd.f.current->indent+1;
  302.      start_make_fold(False);
  303.      bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  304.      move_down();
  305.      bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  306.      make_fold();
  307.      bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  308.      if (!((bd.f.cur_line_typ&START_FOLD) && bd.m.select_mode==no_selection))
  309.       /*{{{  error return*/
  310.       { f_l_failed:
  311.  
  312.         msg_message(M_FAILED);
  313.         return;
  314.       }
  315.       /*}}}  */
  316.    }
  317.    /*}}}  */
  318.   file_fold(tmp_file,(FILE*)0);
  319.   /*}}}  */
  320.   if (!test_linetyp(*bd.f.current,START_FILED))
  321.    /*{{{  error return*/
  322.    { f_l_unfold:
  323.  
  324.      if (text) unfold();
  325.      unlink((char*)tmp_file);
  326.      goto f_l_failed;
  327.    }
  328.    /*}}}  */
  329.   /*{{{  read file back again*/
  330.   ustrcat(filter,one_space);
  331.   ustrcat(filter,tmp_file);
  332.   force_sh=ocl_var[var_force_sh].v;
  333.   if (!(read_pipe=open_shell((char*)filter,"r")))
  334.    /*{{{  error return*/
  335.    { f_l_unfile:
  336.  
  337.      file_fold((unsigned char*)0,(FILE*)0);
  338.      goto f_l_unfold;
  339.    }
  340.    /*}}}  */
  341.   file_fold((unsigned char*)0,read_pipe);
  342.   if ((ocl_var[var_ocl_arg].v=close_shell(read_pipe))<0)
  343.      err_message(M_CLOSE_FAILED,M_PSTR);
  344.   if (test_linetyp(*bd.f.current,START_FILED))
  345.    /*{{{  error return*/
  346.      goto f_l_unfile;
  347.    /*}}}  */
  348.   if (text)
  349.      unfold();
  350.   /*}}}  */
  351.   unlink((char*)tmp_file);
  352.   return;
  353. }
  354. /*}}}  */
  355.  
  356. public void filter_op(boolean full)
  357.  { boolean text;
  358.    unsigned char filter[LINELEN+_POSIX_PATH_MAX+1];
  359.  
  360.    /*{{{  check errors*/
  361.    if (bd.m.dialect.typ==F_C_TDS)
  362.     { msg_message(M_NOT_IF_TDS);
  363.       goto unchange_return;
  364.     }
  365.    else if (bd.m.dir_edit)
  366.     { msg_message(M_DIR_EDIT);
  367.       goto unchange_return;
  368.     }
  369.    text=False;
  370.    if (!full)
  371.     { ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check_cur_linetyp");
  372.       switch (bd.f.cur_line_typ)
  373.        { case NOT_FOLD:
  374.             text=True;
  375.          case START_FOLD:
  376.             break;
  377.          default:
  378.             goto unchange_return;
  379.        }
  380.     }
  381.    /*}}}  */
  382.    /*{{{  get filter command*/
  383.    s_readprompt
  384.     ( filter,
  385.       (unsigned char*)(full?"filter-buffer":"line-filter"),
  386.       LINELEN,
  387.       shell_history
  388.     );
  389.    if (!filter[0] || aborted)
  390.       goto unchange_return;
  391.    /*}}}  */
  392.    if (full)
  393.     { int line_number;
  394.       int scr_level;
  395.  
  396.       ocl_screen_off();
  397.       /*{{{  store position data and create single fold text*/
  398.       line_number=cur_line_no();
  399.       scr_level=bd.scr.cursor.h;
  400.       find_element(1,1);
  401.       bd.scr.cursor.w=1;
  402.       bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  403.       start_make_fold(False);
  404.       skip_to(bd.f.tail);
  405.       bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  406.       make_fold();
  407.       bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  408.       /*}}}  */
  409.       if (test_linetyp(*bd.f.current,START_FOLD) && bd.m.select_mode==no_selection)
  410.        { filter_line(False,filter);
  411.          /*{{{  restore position*/
  412.          bd.f.cur_line_typ=get_linetyp(*bd.f.current);
  413.          unfold();
  414.          find_element(line_number,scr_level);
  415.          /*}}}  */
  416.        }
  417.       ocl_screen_on();
  418.       restore(1);
  419.     }
  420.    else
  421.       filter_line(text,filter);
  422.    return;
  423.  
  424.  unchange_return:
  425.    try_unchange();
  426.  }
  427. /*}}}  */
  428. /*{{{  pipe_from_command*/
  429. public void pipe_from_command(void)
  430. {
  431.   /*{{{  variables*/
  432.   unsigned char command[_POSIX_PATH_MAX+1];
  433.   FILE *pipein;
  434.   struct lg_dumb lang_dump;
  435.   /*}}}  */
  436.  
  437.   save_lang(&lang_dump);
  438.   /*{{{  errors*/
  439.   if (bd.m.dialect.typ==F_C_TDS)
  440.    { msg_message(M_NOT_IF_TDS);
  441.      goto unchange_return;
  442.    }
  443.   /*}}}  */
  444.   /*{{{  open pipe*/
  445.   s_readprompt(command,(unsigned char*)"pipe-from-command",LINELEN, shell_history);
  446.   if (*command=='\0' || aborted)
  447.      goto unchange_return;
  448.   put_vars();
  449.   force_sh=ocl_var[var_force_sh].v;
  450.   if (!(pipein=open_shell((char*)command,"r")))
  451.    { err_message(M_CANTOPEN,M_PSTR);
  452.      goto unchange_return;
  453.    }
  454.   /*}}}  */
  455.   msg_message(M_READING);
  456.   insert_file((element *)0,bd.f.current->prec,bd.f.current,False,bd.f.real_head,(boolean*)0,(boolean*)0,pipein);
  457.   reset_lang(&lang_dump);
  458.   if ((ocl_var[var_ocl_arg].v=close_shell(pipein))<0)
  459.     err_message(M_CLOSE_FAILED,M_PSTR);
  460.   else
  461.     msg_message(M_READ);
  462.   return;
  463.  
  464. unchange_return:
  465.   try_unchange();
  466. }
  467. /*}}}  */
  468. /*{{{  pipe_to_command*/
  469. public void pipe_to_command(void)
  470. {
  471.   /*{{{  variables*/
  472.   unsigned char command[_POSIX_PATH_MAX+1];
  473.   FILE *pipeout;
  474.   change_status ch=bd.m.file_changed_status;
  475.   /*}}}  */
  476.  
  477.   if (bd.f.tail!=bd.f.real_tail)
  478.      msg_message(M_NO_TOP);
  479.   else if (bd.m.dialect.typ==F_C_TDS)
  480.      msg_message(M_NOT_IF_TDS);
  481.   else
  482.    {
  483.      /*{{{  open pipe*/
  484.      s_readprompt(command,(unsigned char*)"pipe-to-command",LINELEN, shell_history);
  485.      if (*command=='\0' || aborted) return;
  486.      put_vars();
  487.      force_sh=ocl_var[var_force_sh].v;
  488.      if (!(pipeout=open_shell((char*)command,"w")))
  489.       { err_message(M_CANTWRITE,M_PSTR);
  490.         return;
  491.       }
  492.      /*}}}  */
  493.      msg_message(M_WRITING);
  494.      total_save(pipeout);
  495.      /*{{{  maybe reset cf-Flag*/
  496.      if (ch!=unchanged_file) {
  497.        bd.m.file_changed_status=ch;
  498.        title_op(CHGTITLE);
  499.      }
  500.      /*}}}  */
  501.      if ((ocl_var[var_ocl_arg].v=close_shell(pipeout))<0)
  502.         err_message(M_CLOSE_FAILED,M_PSTR);
  503.      else
  504.         msg_message(M_WRITTEN);
  505.    }
  506. }
  507. /*}}}  */
  508. /*{{{  dump_file*/
  509. public char *dump_file(void)
  510. { char *name;
  511.  
  512.   name=0;
  513.   if
  514.    (    (bd.m.file_changed_status!=unchanged_file)
  515.      && (!bd.m.dir_edit)
  516.      && (bd.f.real_tail!=bd.f.real_head)
  517. #ifdef OS_NULL_DEVICE
  518.      && ustrcmp(get_data(bd.f.real_tail),(unsigned char*)OS_NULL_DEVICE)
  519. #endif
  520.      && (name=tmpnam((char*)0))
  521.    )
  522.    { no_fold_out=False;
  523.      write_fold((unsigned char*)name,bd.f.real_head->next,(FILE*)0);
  524.      CHMOD_PRIVATE(name);
  525.    }
  526.   return(name);
  527. }
  528. /*}}}  */
  529. /*{{{  save_file*/
  530. public void save_file(boolean const to_top)
  531. {
  532.   msgtyp m;
  533.  
  534.   if (bd.m.file_changed_status==unchanged_file)
  535.      m=M_NO_CHANGE;
  536.   else if (bd.m.dir_edit)
  537.      m=M_DIR_EDIT;
  538.   else if (bd.f.tail != bd.f.real_tail && !to_top)
  539.      m=M_NO_TOP;
  540.   else
  541.    { total_save((FILE*)0);
  542.      if (!bd.f.count_comment_line)
  543.         title_op(CHGXY);
  544.      bd.f.count_comment_line=True;
  545.      return;
  546.    }
  547.   msg_message(m);
  548. }
  549. /*}}}  */
  550. /*{{{  auto_write*/
  551. #ifdef AUTOSAVE_FILE
  552.    public boolean autosave_done=False;
  553. #endif
  554.  
  555. public void auto_write(void)
  556. {
  557.   if (bd.m.file_changed_status!=unchanged_file)
  558.    { msgtyp m;
  559.  
  560.      if (bd.m.dir_edit)
  561.         m=M_DIR_EDIT;
  562.      else if (bd.f.tail == bd.f.real_tail)
  563.       /*{{{  save*/
  564.       {
  565. #       ifdef AUTOSAVE_FILE
  566.            write_fold(AUTOSAVE_FILE, bd.f.real_head->next, (FILE*)0);
  567.            autosave_done=True;
  568. #       else
  569.            total_save((FILE*)0);
  570. #       endif
  571.         m=M_AUTO_SAVED;
  572.       }
  573.       /*}}}  */
  574.      else
  575.         m=M_NO_TOP_AUTO_SAVE;
  576.      msg_message(m);
  577.    }
  578. }
  579. /*}}}  */
  580. /*{{{  add_edit_file*/
  581. public int add_edit_file(char const * const name,int line,boolean no_cmd_line)
  582. {
  583.   if (name)
  584.    { if (name[0])
  585.       /*{{{  add additional entry*/
  586.       { edit_file_buffer *x=file_ring;
  587.  
  588.         /*{{{  search in list*/
  589.         do
  590.          { if (x->filename && !strcmp(name,x->filename))
  591.             { current_ring_file=x;
  592.               goto line_update;
  593.             }
  594.            x=x->next;
  595.          }
  596.         while (x!=file_ring);
  597.         /*}}}  */
  598.         /*{{{  add entry*/
  599.         { if (!(x=ori_malloc(sizeof(edit_file_buffer))))
  600.              exit_origami(r_mem_full,M_NO_MEMORY);
  601.           x->next=file_ring->next;
  602.           x->filename=file_ring->filename;
  603.           file_ring->next=x;
  604.           /*{{{  set filename*/
  605.           if (no_cmd_line)
  606.            { if (!(file_ring->filename=ori_malloc(strlen(name)+1)))
  607.                 exit_origami(r_mem_full,M_NO_MEMORY);
  608.              strcpy((char*)file_ring->filename,name);
  609.            }
  610.           else
  611.            { cmd_last=file_ring;
  612.              file_ring->filename=name;
  613.            }
  614.           /*}}}  */
  615.           file_ring->last_line=1;
  616.           current_ring_file=file_ring;
  617.           file_ring=x;
  618.           ring_size++;
  619.         }
  620.         /*}}}  */
  621.       }
  622.       /*}}}  */
  623.      else
  624.         current_ring_file = file_ring;
  625.    }
  626.   line_update:
  627.   if (current_ring_file && line >=0)
  628.      current_ring_file->last_line=line;
  629.   if (current_ring_file && name && name[0])
  630.    { edit_file_buffer *x=file_ring;
  631.      int i=0;
  632.  
  633.      while (x!=current_ring_file) { x=x->next;i++; }
  634.      return(i);
  635.    }
  636.   else
  637.      return(0);
  638. }
  639. /*}}}  */
  640. /*{{{  fileno2name*/
  641. public unsigned char const *fileno2name(int no)
  642. { edit_file_buffer *x;
  643.  
  644.   if (!(x=file_ring) || no<0)
  645.      return(0);
  646.   while (no--)
  647.      x=x->next;
  648.   return((unsigned char*)x->filename);
  649. }
  650. /*}}}  */
  651. /*{{{  gen_arg_list*/
  652. public void gen_arg_list(element *hd,element *tl)
  653. { edit_file_buffer *s;
  654.   element *x, *y, *last;
  655.  
  656.   /*{{{  read list of argument file*/
  657.   s=file_ring;
  658.   set_data(hd->next,(unsigned char *)STR_EDT_FILE,False);
  659.   set_0_data(tl);
  660.   bd.f.current=hd->next;
  661.   last=hd->next;
  662.   do
  663.    /*{{{  append a line*/
  664.    { if (s->filename)
  665.       {
  666.         /*{{{  line*/
  667.         y=proc_new_element();
  668.         set_linetyp(*y,START_FILED);
  669.         y->x.fold.close_line=DEF_CURSOR_LINE;
  670.         y->x.fold.UU.U1.type=DEFAULT_TYPE;
  671.         y->x.fold.UU.U1.contents=TEXT_CONTENTS;
  672.         y->indent=0;
  673.         y->x.fold.UU.U1.indent=0;
  674.         set_data(y,(unsigned char *)s->filename,False);
  675.         /*}}}  */
  676.         /*{{{  close the fold*/
  677.         x=proc_new_element();
  678.         set_linetyp(*x,END_FOLD);
  679.         x->x.fold.other_end=y;
  680.         x->prec=y;
  681.         y->x.fold.data=x;
  682.         y->x.fold.other_end=x;
  683.         set_data(x,(unsigned char *)s->filename,False);
  684.         /*}}}  */
  685.         join_links(last,y);
  686.         join_links(y,bd.f.tail);
  687.         last=y;
  688.         if (s==current_ring_file) bd.f.current=y;
  689.         if (s==cmd_last && s->next!=file_ring)
  690.          /*{{{  insert a empty line*/
  691.          { x=proc_new_element();
  692.            join_links(last,x);
  693.            join_links(x,bd.f.tail);
  694.            last=x;
  695.          }
  696.          /*}}}  */
  697.       }
  698.      s=s->next;
  699.    }
  700.    /*}}}  */
  701.   while (s!=file_ring);
  702.   current_ring_file=file_ring;
  703.   /*}}}  */
  704.   /*{{{  modes*/
  705.   bd.m.dir_edit=True;
  706.   bd.m.file_changed_status=unchanged_file;
  707.   title_op(CHGTITLE);
  708.   /*}}}  */
  709.   restore_element(DEF_CURSOR_LINE);
  710.   bd.m.dialect.typ = F_C_NONE;
  711.   title_op(CHGTITLE);
  712. # ifdef WINDOW_TITLE_CHANGE
  713.      wt_buff_id= -1;
  714. # endif
  715. }
  716. /*}}}  */
  717. /*{{{  open_arg_list*/
  718. public void open_arg_list(void)
  719. { element *x;
  720.  
  721.   add_edit_file((char*)0,cur_line_no(),False);
  722.   /*{{{  prepare open file*/
  723.   if (bd.f.real_head && bd.f.real_tail) delete_list(bd.f.real_head, bd.f.real_tail);
  724.   /*}}}  */
  725.   /*{{{  create empty file*/
  726.   bd.f.head=proc_new_element();
  727.   bd.f.head->prec = 0;
  728.   bd.f.tail=proc_new_element();
  729.   bd.f.tail->next = 0;
  730.   x=proc_new_element();
  731.   join_links(bd.f.head, x);
  732.   join_links(x, bd.f.tail);
  733.   set_linetyp(*x,START_ENTER_FILED);
  734.   x->x.fold.other_end = bd.f.tail;
  735.   bd.f.tail->x.fold.other_end = x;
  736.   set_linetyp(*bd.f.tail,END_FOLD);
  737.   bd.f.real_head = bd.f.head;
  738.   bd.f.real_tail = bd.f.tail;
  739.   if (!bd.m.user_view) bd.m.read_only=False;
  740.   /*}}}  */
  741.   bd.f.entered=0;
  742.   gen_arg_list(bd.f.real_head,bd.f.real_tail);
  743.   bd.e.file_no=add_edit_file((char*)get_data(bd.f.real_tail),cur_line_no(),True);
  744. # ifdef WINDOW_TITLE_CHANGE
  745.      wt_buff_id= -1;
  746. # endif
  747.   title_op(CHGXY);
  748.   call_number_macro(auto_macro);
  749.   warn_mult_edit();
  750. }
  751. /*}}}  */
  752. /*{{{  open_file*/
  753. public void open_file(boolean const ignore_changed)
  754. {
  755.   unsigned char name[_POSIX_PATH_MAX+1];
  756.  
  757.   add_edit_file((char*)0,cur_line_no(),False);
  758.   if
  759.    (   !ignore_changed
  760.     && bd.m.file_changed_status!=unchanged_file
  761.     && yes(get_msg(M_CHANGED_SAVE))
  762.    )
  763.    { total_save((FILE*)0);
  764.      if (bd.m.file_changed_status!=unchanged_file) return;
  765.    }
  766.   if (aborted)
  767.      return;
  768.   if (!filearg)
  769.    { filearg=name;
  770.      fileprompt(name);
  771.    }
  772.   if (aborted)
  773.      return;
  774.   bd.e.file_no=add_edit_file((char*)filearg,-1,True);
  775.   if (!bd.m.user_view) bd.m.read_only=False;
  776.   delete_list(bd.f.real_head, bd.f.real_tail);
  777.   bd.f.entered=0;
  778.   create_list();
  779. # ifdef WINDOW_TITLE_CHANGE
  780.      wt_buff_id= -1;
  781. # endif
  782.   restore_element(DEF_CURSOR_LINE);
  783.   bd.m.file_changed_status=unchanged_file;
  784.   title_op(CHGXY);
  785.   call_number_macro(auto_macro);
  786.   warn_mult_edit();
  787. }
  788. /*}}}  */
  789. /*{{{  next_file*/
  790. private void next_file(int of, boolean ignore_changed)
  791. { edit_file_buffer *x=file_ring,*cur=current_ring_file;
  792.  
  793.   /*{{{  shift next*/
  794.   while (of>0)
  795.    { of--;
  796.      while (x!=cur) x=x->next;
  797.      cur=x->next;
  798.    }
  799.   /*}}}  */
  800.   /*{{{  shift previous*/
  801.   while (of<0)
  802.    { of++;
  803.      while (x->next!=cur) x=x->next;
  804.      cur=x;
  805.    }
  806.   /*}}}  */
  807.   filearg=(unsigned char*)cur->filename;
  808.   if
  809.    (    !ignore_changed
  810.      && bd.m.file_changed_status!=unchanged_file
  811.      && yes(get_msg(M_CHANGED_SAVE))
  812.    )
  813.    { total_save((FILE*)0);
  814.      if (bd.m.file_changed_status!=unchanged_file) return;
  815.     }
  816.   if (aborted) return;
  817.   if (filearg) open_file(ignore_changed); else open_arg_list();
  818.   if (current_ring_file)
  819.      find_element(current_ring_file->last_line,DEF_CURSOR_LINE);
  820. }
  821. /*}}}  */
  822. /*{{{  open_list_file*/
  823. public void open_list_file(void)
  824. { int i;
  825.   boolean ask;
  826.   unsigned char name[16];
  827.  
  828.   ask=ocl_var[var_mod_beh].v==0;
  829.   if (!ask)
  830.      i=ocl_var[var_mod_beh].v-1;
  831.   if (bd.m.file_changed_status!=unchanged_file && yes(get_msg(M_CHANGED_SAVE)))
  832.    { total_save((FILE*)0);
  833.      if (bd.m.file_changed_status!=unchanged_file) return;
  834.    }
  835.   if (aborted)
  836.      return;
  837.   if (ask)
  838.    { s_readprompt(name,get_msg(M_FILEPO),15,misc_history);
  839.      if (aborted)
  840.         return;
  841.      i=atoi((char*)name);
  842.    }
  843.   if (i<0)
  844.     i=ring_size-1;
  845.   else if (i>=ring_size)
  846.      i=0;
  847.   next_file(i-bd.e.file_no,True);
  848. }
  849. /*}}}  */
  850. /*{{{  enter_list_file*/
  851. public void enter_list_file(void)
  852. { int i;
  853.   unsigned char name[16];
  854.   unsigned char const *s;
  855.  
  856.   s_readprompt(name,get_msg(M_FILEPO),15,misc_history);
  857.   if (aborted) return;
  858.   i=atoi((char*)name);
  859.   if (i<0 || i>ring_size || !(s=fileno2name(i)) || !*s)
  860.      s=(unsigned char*)empty_text;
  861.   enter_fold(s);
  862. }
  863. /*}}}  */
  864. /*{{{  write_file*/
  865. public void write_file(void)
  866. {
  867.   if (bd.f.tail == bd.f.real_tail)
  868.    { unsigned char newfilename[_POSIX_PATH_MAX+1];
  869.  
  870.      fileprompt(newfilename);
  871.      if (*newfilename != '\0' && !aborted)
  872.       { if ((bd.m.dialect.typ != F_C_TDS) && yes(get_msg(M_LIST)))
  873.            no_fold_out=True;
  874.         if (!aborted)
  875.            write_fold(newfilename, bd.f.real_head->next,(FILE*)0);
  876.         no_fold_out=False;
  877.       }
  878.    }
  879.   else
  880.      msg_message(M_NO_TOP);
  881. }
  882. /*}}}  */
  883.